%% @doc templerl のテスト
%%
-module(t_templ).
-import(templ, [init/0,init/1,process/1,process/2,process/3,process/4]).

-include_lib("eunit/include/eunit.hrl").

process_test_() ->
	init(),

	[?_assertMatch("123", 
				   process("123")),
	 ?_assertMatch("hoge123", 
				   process("hoge\{123\}")),
	 ?_assertMatch("123hoge", 
				   process("\{123\}hoge")),
	 ?_assertMatch("hoge123hoge", 
				   process("hoge{123}hoge")),
	 ?_assertMatch("}", 
				   process("}")),
	 ?_assertError(badstate,
				   process("{"))
	].

process_expr_test_() ->
	init([{"greetings","Hello {user}"}, {"user","{title} Joe"}, {"title", "Mr."},
		  {"jgreetings","こんにちは、\{juser\} 様"}, {"juser","山田太郎"}]),

	[?_assertMatch("123", 
				   process("\{123\}")),

	 ?_assertMatch("true", 
				   process("{true}")),

	 ?_assertMatch("Hello Mr. Joe !",
				   process(process(process("{greetings} !")))),
	 ?_assertMatch("こんにちは、山田太郎 様！",
				   process(process("{jgreetings}！"))),

	 ?_assertMatch("true", 
				   process("\{true || false && true==false\}")),
	 ?_assertMatch("false", 
				   process("\{(true || false) && true!=true\}")),
	 ?_assertMatch("false", 
				   process("\{!(true || false) || true!=true\}")),
	 ?_assertMatch("true", 
				   process("\{123 == 123 && 123 != 456 && 
                              123 < 456 && 123 <= 123 &&
                              456 > 123 && 123 >= 123\}")),
	 ?_assertError({badarg, _}, process("\{true || 1\}")),
	 ?_assertError({badarg, _}, process("\{true && \"true\"\}")),
	 ?_assertError({badarg, _}, process("\{1 && \"true\"\}")),

	 ?_assertMatch("false", 
				   process("\{0 == 1 || 0 != 0 || 
                              1 < 0 || 0 < 0 || 1 <= 0 || 
                              0 > 1 || 0 > 0 || 0 >= 1\}")),
	 ?_assertMatch("true",
				   process("\{0 == 0 && 0 == -0 && -1 < 1\}")),
	 ?_assertMatch("true",
				   process("\{\"abc\" == \"abc\" && \"a\" != \"\" && \"\\u3299\" == \"㊙\"\}")), % "
	 ?_assertMatch("false",
				   process("\{true == 0 || true == \"true\" || 123 == \"123\"\}")),
	 ?_assertMatch("true",
				   process("\{true != 1 && true != \"false\" && 0 != \"1\"\}")),
	 ?_assertError({badarg, _}, process("\{false < true\}")),
	 ?_assertError({badarg, _}, process("\{0 <= true\}")),
	 ?_assertError({badarg, _}, process("\{false < \"true\"\}"))
	].

process_expr1_test_() ->
	init([{"title","My Homepage"}, {"names",["John","Gary","Gregg","James"]},
		  {"ten", 10}, {"bool", true}]),

	[?_assertMatch("Welcome to My Homepage", 
				   process("Welcome to {title}")),
	 ?_assertMatch("Hello John",
				   process("Hello {names[1]}")),

	 ?_assertMatch("77 121",
				   process("{title[1]} {title[2]}")),
	 ?_assertError(function_clause,
				   process("{names[10]}")),
	 ?_assertError(function_clause,
				   process("{ten[1]}")),
	 ?_assertError(function_clause,
				   process("{bool[1]}"))
	].

process_erlangcall_test_() ->
	init(),

	[?_assertMatch("hoge", 
				   process("{erlang:list_to_atom(\"hoge\")}")),
	 ?_assertMatch("ge",
				   process("\{string :\n substr (\"hoge\", 3)\}"))
	].
	
process_erlangcall1_test_() ->
	init([{"module",erlang}, 
		  {"l2a",list_to_atom}, {"l2i",list_to_integer},
		  {"string",[{"module",string}, {"substr",substr}]}]),

	[?_assertError(undef, 
				   process("\{module:l2a(\"hoge\")\}")),
	 ?_assertError(_,
				   process("\{module:l2\na(\"hoge\")\}")),
	 ?_assertMatch("ge",
				   process("\{string.module\n : string.substr (\"hoge\", 3)\}")),
	 % duplicated
	 ?_assertMatch("hoge", 
				   process("\{module l2a(\"hoge\")\}")),
	 ?_assertError({novalue,_},
				   process("\{module l2\na(\"hoge\")\}")),
	 ?_assertMatch("ge",
				   process("\{string.module\n string.substr (\"hoge\", 3)\}"))
	].

process_with_ctx_test_() ->
	[
	 ?_assertMatch("string", 
				   process("\{module\}", [{"module",string}, {"substr",substr}])),
	 ?_assertMatch("string", 
				   process("\{module\}")),
	 ?_assertMatch("ge", 
				   process("\{module substr (\"hoge\", 3)\}")),

	 ?_assertMatch("hello joe", 
				   process(process("{greetings}", [{"greetings", "hello {name}"}]), [{"name", "joe"}])),
	 ?_assertError(_, 
				   process("\{module\}"))
	].

process_with_delim_test_() ->
	[
	 ?_assertMatch("hogehoge", 
				   process("hoge{{hoge}}", [{"hoge",hoge}], "{{", "}}")),
	 ?_assertMatch("falsehoge", 
				   process("===hoge==hoge===hoge", [{"hoge",hoge}], "===", "==="))
	].
